package cn.bj.yu.single;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/**
 * @author 周宇
 * @create 2020-08-16 2:43
 * 正常的 懒汉式单例->并发环境，发现单例失效->DCL懒汉式!
 */
public class LazyMan {

    private static boolean flag = false;

    private LazyMan() {
        synchronized (LazyMan.class) {
            if(flag==false){
                flag=true;
            }else{
                throw new RuntimeException("不要试图用反射破坏单例模式");
            }
        }
    }

    private volatile static LazyMan lazyMan;

    public static LazyMan getInstance() {
        if (lazyMan == null) {
            lazyMan = new LazyMan();
        }
        return lazyMan;
    }

    //万恶的反射
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        // 通过反射创建对象
        Field flag = LazyMan.class.getDeclaredField("flag");
        flag.setAccessible(true);

        // 通过反射实例化对象
        Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
        declaredConstructor.setAccessible(true);//无视private
        LazyMan instance = declaredConstructor.newInstance();
        System.out.println(flag.get(declaredConstructor));
        System.out.println(instance.hashCode());

        //通过反射，修改字段的值！
        flag.set(instance,false);
        LazyMan instance2 = declaredConstructor.newInstance();
        System.out.println(flag.get(declaredConstructor));
        System.out.println(instance2.hashCode());
    }
}
